home *** CD-ROM | disk | FTP | other *** search
/ Graphics Plus / Graphics Plus.iso / general / procssng / ccs / ccs-11tl.lha / lbl / x11 / tuner / canvas / update.c < prev   
Encoding:
C/C++ Source or Header  |  1993-06-06  |  27.6 KB  |  983 lines

  1. /*
  2. %    UPDATE . C
  3. %
  4. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  5.  
  6. This software is copyright (C) by the Lawrence Berkeley Laboratory.
  7. Permission is granted to reproduce this software for non-commercial
  8. purposes provided that this notice is left intact.
  9.  
  10. It is acknowledged that the U.S. Government has rights to this software
  11. under Contract DE-AC03-765F00098 between the U.S.  Department of Energy
  12. and the University of California.
  13.  
  14. This software is provided as a professional and academic contribution
  15. for joint exchange. Thus, it is experimental, and is provided ``as is'',
  16. with no warranties of any kind whatsoever, no support, no promise of
  17. updates, or printed documentation. By using this software, you
  18. acknowledge that the Lawrence Berkeley Laboratory and Regents of the
  19. University of California shall have no liability with respect to the
  20. infringement of other copyrights by any part of this software.
  21.  
  22. For further information about this notice, contact William Johnston,
  23. Bld. 50B, Rm. 2239, Lawrence Berkeley Laboratory, Berkeley, CA, 94720.
  24. (wejohnston@lbl.gov)
  25.  
  26. For further information about this software, contact:
  27.     Jin Guojun
  28.     Bld. 50B, Rm. 2275, Lawrence Berkeley Laboratory, Berkeley, CA, 94720.
  29.     g_jin@lbl.gov
  30.  
  31. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  32. %
  33. %    Run time handlers to update picture, and file handling
  34. %    Including:
  35. %        Panel_init(), MapColor(), SetColormap(),
  36. %        FileAccess(), LoadFile(), HistoHandle()
  37. %
  38. %    The Panel_init() build a control panel for both color and
  39. %    gray-scale interactive analyst.
  40. %
  41. % AUTHOR:    Jin Guojun - LBL    4/1/1991
  42. */
  43.  
  44. #ifndef    ETAButtonColor
  45. #define    ETAButtonColor    3
  46. #endif
  47.  
  48. #include "tuner.h"
  49.  
  50. #ifdef    C_TUNER
  51. char    *FRM[] = {"Red", "Green", "Blue", "Sync"};
  52. #else
  53. char    *FRM[] = {"  0/000", "Frame", "Prev", "Next"};
  54. #endif
  55.  
  56.  
  57. Panel_init(parent, ela_scale, PBGcolor, map_panel)
  58. WinAttribute    *parent;
  59. {
  60. char    buf[128];
  61.  
  62. sprintf(buf, "Elasitc TUNER and ANALYZER -- %d %s", ncolors,
  63. #ifdef    C_TUNER
  64. "colors"
  65. #else
  66. "grey levels"
  67. #endif
  68. );
  69. Epanel = CreatePanel(100, 200, 512, 360, buf, parent,
  70.         EnterWindowMask | LeaveWindowMask);
  71. XSetWindowBackground(parent->dpy, Epanel->win, PBGcolor);
  72. if (map_panel)
  73.     XMapWindow(Epanel->dpy, Epanel->win);
  74.  
  75. fontWidth = Epanel->font_w;
  76. fontHeight = Epanel->font_h;
  77.  
  78.     /*    Quantization    */
  79. QSlider = CreateSlider(Epanel, 192, 270, 5, -300, 100, 1, 0, "Quantizing", "",
  80.         Blue, lightGray);
  81.  
  82. #ifdef    C_TUNER
  83. QButton = CreateButton(Epanel, 144, 261, 2, "Fixed Panel Color", NF,
  84.         Visible, Light);
  85. fButton = CreateButton(Epanel, 64, 51, 4, "Channel", FRM, Visible, Light);
  86. QSlider->valid = False;        /* never used, but easy.    */
  87. ButtonState(QButton) = True;    /* Change colors with image    */
  88. #else
  89. QButton = CreateButton(Epanel, 16, 261, 2, "", NF, Visible, Light);
  90. fButton = CreateButton(Epanel, 16, 51, 4, "", FRM, Visible, Light);
  91. /* fButton = CreateButton(Epanel, 64, 51, 3, "Frame", FRM, Visible, Gray);*/
  92. strcpy(filelist[MENU3_LDFrm-1], "......");    /* invalid */
  93. #endif
  94.  
  95. ESlider = CreateSlider(Epanel, 75, 174, ela_scale, -200*ela_scale, 200*ela_scale,
  96.     1, 0, "Tuner", "<- Gamma -> | <-  S  -> | <- Gamma ->", White, Visible);
  97. SetSBarRPos(ESlider, 0, 1);
  98. LSlider = CreateSlider(Epanel, 100, 174, 1, 0, 255, 2, 0, "Scale", "Linear",
  99.         White, lightGray);
  100. DButton = CreateButton(Epanel, 50, 303, 2, "DATA", DUP, Visible, Light);
  101.     /*    clip control    */
  102. CSlider = CreateSlider(Epanel, 312, 72, 2, 0, 254, 2, 0, "Clip", "",
  103.         Blue, lightGray);
  104. SetSBarRPos(CSlider, 254, 2);    /* init    to no clip */
  105. Interpolate = CreateButton(Epanel, 420, 261, 2, "Interpolation", NF,
  106.         Visible, Light);
  107.     /* Other Buttons */
  108. ZButton = CreateButton(Epanel, 420, 204, 2, "ZERO", NF, Visible, Light);
  109. EButton = CreateButton(Epanel, 100, 204, 3, "Emphasis", BN1,
  110.         lightGray, parent->dpy_depth==8 ? ETAButtonColor : Blue);
  111. RstButt = CreatePressButton(Epanel, 354, 300, "RESET", Gray);
  112. rfsButt = CreatePressButton(Epanel, 435, 300, "Refesh", Gray);
  113. FButton = CreateButton(Epanel, 16, 12, 3, "", BNF, Visible, Light);
  114. hButton = CreateButton(Epanel, 16, 96, 5, "", HST, Visible, Light);
  115. heqButt = CreatePressButton(Epanel, 435, 96, "histeq", Light);
  116. slider = LSlider;            /* overlayed, init to linear */
  117. ButtonState(EButton) = ETALinear;    /* init to linear */
  118.     /* PULL DOWN MENU */
  119. ctrlmenu = CreatePopMenu(Epanel, parent, "Editer", ctrlist, numctrl);
  120. paramenu = CreatePopMenu(Epanel, parent, "SCALEs", paralist, numpara);
  121. filemenu = CreatePopMenu(Epanel, parent, "FILE", filelist, numcomd);
  122. fontmenu = CreatePopMenu(Epanel, parent, "Fonts", fontlist, numfont);
  123. NoteWin = CreatePanel(10, 10, 256, 128, "MESSAGE", parent, NULL);
  124. InfoWin = CreatePanel(10, 10, 512, 256, "Information", parent, NULL);
  125. MsgButton = CreateButton(NoteWin, 24, 16, 1, "", NOTEMSG, Visible, Gray);
  126. YesButt = CreatePressButton(NoteWin, 48, 80, " Yes ", Light);
  127. NoButt = CreatePressButton(NoteWin, 144, 80, " No ", Light);
  128. OkButt = CreatePressButton(NoteWin, 96, 80, " OK ", Light);
  129. AbortButt = CreatePressButton(NoteWin, 96, 80, " Abort ", Light);
  130.  
  131. return    map_panel;
  132. }
  133.  
  134. /*===============================================
  135. %    to reset original image parameter    %
  136. ===============================================*/
  137. void
  138. ResetORange(img)
  139. Image    *img;
  140. {
  141. register Mregister*    mmm;
  142.     if (img->setscale)
  143.         mmm = &(img->mmm);
  144.     else if (img->color_dpy)
  145.         mmm = img->marray + img->fn%img->channels;
  146.     else    mmm = img->marray + img->fn;
  147.     if (mmm->max < mmm->min  || mmm->max < VCTEntry)
  148.         mmm->max = MaxColors-1;    /* never show small max value */
  149.     SetSBarRPos(LSlider, img->linearlow=
  150. #ifdef    DIRECT
  151.         MAX(VCTEntry, mmm->min), 1);
  152. #else
  153.         mmm->min, 1);
  154. #endif
  155.     SetSBarRPos(LSlider, img->linearup=mmm->max, 2);
  156.     if (slider==LSlider)
  157.         DrawSlider(slider);
  158. }
  159.  
  160.  
  161. /* RETURNs:    (-1) newfile;    (n) reload n;    (0) save, or errors for load */
  162.  
  163. static    char    tbuf[128];
  164.  
  165. FileAccess(imgp, max_num, noi)    /* number of images in stack */
  166. Image    *imgp[];
  167. {
  168. FILE*    fp;
  169. char    info[128], errinfos[32];
  170. register int    i=0;
  171. bool    state=0;
  172. struct    stat    statbuf;
  173. #define    PCloseWin    "Not enough memory. Press 'c' to close some image"
  174.  
  175. if (ButtonState(FButton)==FileSave) {
  176.     for (i=noi; i--;)
  177.     if (imgp[i]->active)    break;
  178.     if (i<0)    goto    FDone;        /* no active image */
  179.     strcpy(tbuf, imgp[noi=i]->name);    /* noi point to active image */
  180.     if (imgp[noi]->frames > 1 &&
  181.     YesOrNo("Save ALL frames ? YES/NO\n(NO, save current frame)",
  182.     NoteWin->font_h))    {
  183.         imgp[noi]->save_all = imgp[noi]->frames;
  184.     }    else    imgp[noi]->save_all = imgp[noi]->frames<=1;
  185.     PressButtonState(YesButt) = PressButtonState(NoButt) = RESETSTATE;
  186. }
  187. FRedo:    DispInfo(Epanel, 0,
  188.     "INPUT -- TAB to cat, BS to correct, ESC undo or TYPE new one",    Yellow);
  189. if (state=TextLine(FButton, tbuf, sizeof(tbuf), 0, Exposure_handler, imgp, noi))
  190.     switch (ButtonState(FButton))    {
  191.     case FileLoad:
  192.         if (noi >= max_num)    {
  193.             for (i=noi; i--;)
  194.                 if (strcmp(tbuf, imgp[i]->name)==0)    break;
  195.             if (i<0)    {
  196.                 XBell(Epanel->dpy, state=0);
  197.                 WaitOk(NULL, PCloseWin, 0);
  198.                 break;
  199.             }
  200.             fsize = imgp[noi=i]->width*imgp[i]->height;
  201.         }
  202.         if (imgp[noi] && imgp[noi]->update)    {
  203.             sprintf(info, "save %s ? y/n", imgp[noi]->name);
  204.             i = (strlen(info)+2) * Epanel->font_w;
  205.             DispInfo(Epanel, 0, info, white1);
  206.             info[0] = 0;
  207.             TextLine(FButton, info, sizeof(info), i,
  208.                 Exposure_handler, imgp, noi);
  209.             if (info[0] != 'n')    {
  210.             char    sbuf[128];
  211.                 strcpy(sbuf, tbuf);
  212.                 ButtonState(FButton) = FileSave;
  213.                 FileAccess(imgp, max_num, noi+1);
  214.                 strcpy(tbuf, sbuf);
  215.             }
  216.         }
  217.         sprintf(info, "Loading file %s", tbuf);
  218.         DispInfo(Epanel, 0, info, Red);
  219.         state = (int)(fp=freopen(tbuf, "rb", stdin));
  220.         if (state) {
  221.             if    (state=LoadImage(fp, imgp+noi, tbuf))
  222.             if (state>0)    state = EOF;
  223.             else /* < 0 */    state = noi;
  224.             else    sprintf(errinfos, "%s is wrong File", tbuf);
  225.         }
  226.         else    sprintf(errinfos, "File not found");
  227.         if (!state){
  228.             DispInfo(Epanel, (strlen(info)+1)*Epanel->font_w,
  229.                 errinfos, Green);
  230.             XBell(Epanel->dpy, state);
  231.             WaitOk(NULL, errinfos, 0);
  232.         }
  233.         break;
  234.     case FileSave:
  235.         if (!stat(tbuf, &statbuf)) {
  236.             TopWindow(Epanel, 0);
  237.             DrawPanel();    XFlush(Epanel->dpy);
  238.             sprintf(info, "file %s exist! overwrite ? y/n", tbuf);
  239.             DispInfo(Epanel, 0, info, White);
  240.             i = strlen(info);
  241.             info[0] = 0;
  242.             TextLine(FButton, info, 2, ++i*Epanel->font_w,
  243.                 Exposure_handler, imgp, noi);
  244.             if (info[0] == Esc)    break;
  245.             if (info[0] != 'y')    goto    FRedo;
  246.         }
  247.         fp = freopen(tbuf, "wb", stdout);
  248.         if (!fp){
  249.             DispInfo(Epanel, 256, "can't open", Green);
  250.             XBell(Epanel->dpy, state=0);
  251.             WaitOk(NULL, sys_errlist[errno], 0);
  252.         }
  253.         else {
  254.             imgp[noi]->OUT_FP = fp;
  255.             if (imgp[noi]->o_type != RLE) {
  256.             register Image* img=imgp[noi];
  257.             register char    *av[1];
  258.             int    frames = img->frames,
  259.                 save_info = img->pixmap_failed;
  260.             i = img->save_all;
  261.             if (!i)    i++;
  262.             img->frames = i;
  263.             img->pxl_out = 1;
  264.             img->o_form = IFMT_BYTE;
  265.             ((U_IMAGE*)img)->update_header = (*img->header_handle)
  266.                     (HEADER_TO, img, 0, No);
  267.             sprintf(info, "writing %s", tbuf);
  268.             DispInfo(Epanel, 0, info, White);
  269.             i = ReadSlider(ESlider, 1);
  270.             sprintf(info, "%s ETA -f%d, bf=%d\n",
  271.                 Progname, i, img->curve);
  272.         /* only output a sub-image when img is a single frame image */
  273.             av[0] = info;
  274.             (*img->header_handle)(HEADER_WRITE, img,
  275.                         1, av, img->update);
  276.             img->frames = frames;
  277.             state=(*img->std_swif)(FI_SAVE_FILE, img, NULL,
  278.                 img->save_all ? 0 : img->fn);
  279.             img->pixmap_failed = save_info;
  280.             }
  281.             else {
  282.             register Image* img=imgp[noi];
  283.             bool    add_cmap=0, save_cur=0;
  284.             if (img->dpy_channels==3 || !OsameI) {
  285.                 add_cmap = YesOrNo("apply screen color map ?", 0);
  286.                 PressButtonState(YesButt) =
  287.                 PressButtonState(NoButt) = RESETSTATE;
  288.                 if (img->channels == 3)/* don't save cmap */
  289.                     rle_dflt_hdr.ncmap = 0;
  290.             }
  291.             else if (img->cmaplen && img->in_cmap)
  292.                 regmap_to_rlemap(img->in_cmap, img->cmaplen,
  293.                         img->ncmap, &rle_dflt_hdr);
  294.             save_cur = YesOrNo("save current setting ?", 0);
  295.             PressButtonState(YesButt) =
  296.             PressButtonState(NoButt) = RESETSTATE;
  297.             memcpy(&cmn_hd, img, sizeof(cmn_hd));
  298.             (*img->std_swif)(FI_DESC_ETA, &cmn_hd, info, cer);
  299.             if (rle_dflt_hdr.comments)
  300.                 rle_dflt_hdr.comments[0] = str_save(cmn_hd.desc);
  301.             sprintf(info, "writing %s", tbuf);
  302.             DispInfo(Epanel, 0, info, White);
  303.             state = (*img->std_swif)(FI_SAVE_FILE, img, add_cmap,
  304.                     save_cur ? lkt : NULL);
  305.             }
  306.         fclose(fp);
  307.         }
  308.         break;
  309.     default:    DispInfo(Epanel, 0, "???", Green);
  310.     }
  311. FDone:
  312. ButtonState(FButton)=FileLabel;
  313. DrawButton(FButton);
  314. return    state;
  315. }
  316.  
  317.  
  318. #ifdef    DIRECT
  319.  
  320. bool    frmchange;
  321.  
  322. #ifdef    C_TUNER
  323.  
  324. eta_scan_map(img, eta_map)
  325. U_IMAGE    *img;
  326. {
  327. int    i_factor=get_iconsize(img, 0);
  328. byte    *mp[3], *srcp[3];
  329. register int    i, l, my;
  330.  
  331.     for (l=img->height; l--;)    {
  332.         mp[0] = SAVED_RLE_ROW(img, l);
  333.         if (eta_map)
  334.             srcp[0] = mp[0];
  335.         else    srcp[0] = ORIG_RLE_ROW(img, l);
  336.         for (i=1; i<img->channels; i++)
  337.             mp[i] = mp[i-1] + img->width,
  338.             srcp[i] = srcp[i-1] + img->width;
  339.         MapRGB(0, NULL, &img, srcp, mp, l, img->width, l, i_factor);
  340.     }
  341. }
  342.  
  343. MapColor(img, dp, fsize, colorp, start)
  344. Image    *img;
  345. byte    *dp;
  346. register XColor    *colorp;
  347. {
  348. XColor    TmpColor[MaxColors];
  349. int    maxdiff=img->entries;
  350. register int    i;
  351. register LKT    *lktr=lkt, *lktg=lkt+MaxColors, *lktb=lkt+(MaxColors<<1);
  352. register XColor    *tcp = TmpColor;
  353.  
  354. if (maxdiff > ncolors)
  355.     maxdiff = ncolors;    /* limitation */
  356. else if (maxdiff < 2)    return    prgmerr(0, "map 0 colors");
  357.  
  358. memcpy(tcp, colorp, sizeof(*tcp)*maxdiff);
  359.     for (i=0; i<maxdiff; i++){
  360.         tcp[i].red = lktr[colorp[i].red>>8] << 8;
  361.         tcp[i].green = lktg[colorp[i].green>>8] << 8;
  362.         tcp[i].blue = lktb[colorp[i].blue>>8] << 8;
  363.     }
  364. XStoreColors(img->dpy, img->colormap, tcp, maxdiff);/* load colors to VCT    */
  365. XFlush(img->dpy);
  366. #ifdef    _DEBUG_
  367. dumpColor(img->dpy, img->colormap, cquire);
  368. #endif
  369. }
  370.  
  371. #else
  372.  
  373. /*=======================================================
  374. %    important note:    Since lkt always invoked, so,    %
  375. %    even reset has to put min to lkt[0], not 0.    %
  376. =======================================================*/
  377. MapColor(img, dp, fsize, colorp, start)
  378. Image    *img;
  379. byte    *dp;
  380. register XColor    *colorp;
  381. {
  382. #ifdef    _DEBUG_
  383. time_t    t0, t1;
  384. time(&t0);
  385. #endif
  386.  
  387. register int    i;
  388. int    maxdiff = img->marray[img->fn].max - start + 1;
  389.  
  390. if (maxdiff < 1)
  391.     maxdiff = 1;
  392. /* assign data to image buffer */
  393. img->image->data = (char *) dp;
  394.  
  395. if (img->sub_img) {
  396. register int    j, min=img->marray[img->fn].min;
  397. register LKT    *lktp=lkt;
  398. register byte    *rp = dp + img->sub_img_y * img->width + img->sub_img_x;
  399.     for (i=0; i<img->sub_img_h; i++)    {
  400.     for (j=0; j<img->sub_img_w; j++)
  401.         rp[j] = lktp[(rp[j] - min)&0xFF];
  402.     XPutImage(img->dpy, img->win, img->gc, img->image,
  403.         img->sub_img_x, img->sub_img_y + i,
  404.         img->sub_img_x, img->sub_img_y + i, img->sub_img_w, 1);
  405.     rp += img->width;
  406.     }
  407.     img->update = True;
  408. }
  409. else if (frmchange)    {
  410.     XPutImage(img->dpy, img->win, img->gc, img->image, 0, 0, 0, 0,
  411.         img->width, img->height);
  412.     frmchange=0;
  413. #ifdef    _DEBUG_
  414.     time(&t1);
  415.     if (verbose)    message("time=%d, start=%d, end=%d\n", t1-t0, start, i);
  416. #endif
  417. }
  418. else{
  419.     for (i=start; i<maxdiff+start; i++)    {
  420.     register unsigned short    illuminance, scale=65536 / ncolors;
  421.     colorp[i].pixel = (u_long) i;
  422.     illuminance = scale * lkt[i-start];    /* set i to high byte    */
  423.     colorp[i].red = colorp[i].green = colorp[i].blue = illuminance;
  424.     colorp[i].flags = DoAll;
  425.     }
  426. /*    load colors to VCT    */
  427. XStoreColors(img->dpy, img->colormap, colorp+start, maxdiff);
  428. }
  429. XFlush(img->dpy);
  430. #ifdef    _DEBUG_
  431. dumpColor(img->dpy, img->colormap, cquire);
  432. #endif
  433. }
  434.  
  435. #endif    C_TUNER and Back_to COMMON_DIRECT
  436.  
  437. Colormap
  438. SetColormap(wa, colorp, ncolors, newmap, VcTolerance)
  439. WinAttribute    *wa;
  440. XColor    colorp[];
  441. int    ncolors;
  442. bool    *newmap;
  443. {
  444. register    i;
  445. Colormap    cmap = DefaultColormap(wa->dpy, wa->screen);
  446.  
  447. if (wa->dpy_depth < 24)    {
  448. if (ncolors > XDisplayCells(wa->dpy, wa->screen))
  449.     ncolors = XDisplayCells(wa->dpy, wa->screen);
  450.  
  451. mknew:    message("NMap = %d\n", *newmap);
  452. if (*newmap)    VCTEntry = 24;
  453.  
  454. /* save first serveral entries for system */
  455. for (i=0; i < VCTEntry; i++)    {
  456.     colorp[i].pixel = i;
  457.     XQueryColor(wa->dpy, cmap, &colorp[i]);
  458. }
  459.     if (*newmap){
  460.     cmap = XCreateColormap(wa->dpy, wa->root, wa->visual, AllocAll);
  461.     XStoreColors(wa->dpy, cmap, colorp, ncolors); /* load colors to VCT */
  462.     }
  463.     else{
  464.     u_long    pxl, plane_masks[8];
  465.     /* number > 1 will get trouble. It is a bug. So take time do loop */
  466.     for (i=VcTolerance; i<ncolors; i++)
  467.     if (!XAllocColorCells(wa->dpy, cmap, 0, plane_masks, 0, &pxl, 1)
  468.         && ncolors-i > 4)    {
  469.         register int    j;
  470.         long    pxl[MaxColors];
  471.         msg("can't alloc C_cell %d\n", i);
  472.         i -= VcTolerance;
  473.         for (j=0; j<i; j++)
  474.             pxl[j] = colorp[j+VcTolerance].pixel;
  475.         XFreeColors(wa->dpy, cmap, pxl, j, 0);
  476.         --*newmap;
  477.         goto    mknew;
  478.     }
  479.     else    colorp[i].pixel = pxl;
  480.     XStoreColors(wa->dpy, cmap, colorp+VcTolerance, ncolors-VcTolerance);
  481.     }
  482.     if (arrow && *newmap && ncolors > 254)
  483.     XRecolorCursor(wa->dpy, arrow, colorp[255], colorp[254]);
  484.     if (verbose)
  485.     message("[%d] grey level %d\n", cmap, ncolors-VcTolerance);
  486.     dumpColor(wa->dpy, cmap, cquire);
  487.     XInstallColormap(wa->dpy, cmap);
  488. }
  489. return (wa->cmap=cmap);
  490. }
  491.  
  492. #else    /* B/W regular routines */
  493.  
  494. Colormap
  495. SetColormap(wa, colorp, ncolors, newmap, DoQuant)
  496. WinAttribute    *wa;
  497. XColor    colorp[];
  498. int    *ncolors;
  499. bool    *newmap;
  500. {
  501. register    i;
  502. Colormap    newcmap, cmap = DefaultColormap(wa->dpy, wa->screen);
  503.  
  504. if (wa->dpy_depth < 24)    {
  505. if (*ncolors > XDisplayCells(wa->dpy, wa->screen))
  506.     *ncolors = XDisplayCells(wa->dpy, wa->screen);
  507.  
  508. if (DoQuant){
  509.     newcmap = XCopyColormapAndFree(wa->dpy, cmap);
  510.     XFreeColormap(wa->dpy, newcmap);
  511.     *newmap = 0;
  512. }
  513. if (*newmap){
  514.     cmap = XCreateColormap(wa->dpy, wa->root, wa->visual,
  515.         wa->dpy_depth<24 ? AllocAll : AllocNone);
  516.     XStoreColors(wa->dpy, cmap, colorp, *ncolors);/* load colors to VCT    */
  517.     XInstallColormap(wa->dpy, cmap);
  518.     if (arrow && *ncolors > 254)
  519.         XRecolorCursor(wa->dpy, arrow, colorp[255], colorp[254]);
  520. } else {
  521.     for (i=0; i < *ncolors; i++) {
  522.         if (!XAllocColor(wa->dpy, cmap, &colorp[i])){
  523.         if((colorp[i].pixel=GetCloseColor(wa->dpy, cmap, *ncolors,
  524.             colorp[i].red>>8, colorp[i].green>>8, colorp[i].blue>>8))
  525.             >0)    continue;
  526.         if (*ncolors-i < *ncolors>>ToleranceFactor+1){
  527.             for (i++; i<*ncolors; i++)
  528.                 colorp[i].pixel = colorp[i-1].pixel;
  529.             break;
  530.         }
  531. /* copy i new color in cmap to newcmap and free these entries in cmap */
  532.         newcmap = XCopyColormapAndFree(wa->dpy, cmap);
  533.     /* then throw away the new colormap */
  534.         XFreeColormap(wa->dpy, newcmap);
  535.         *ncolors >>= 1+quant;
  536.         *ncolors = CreateCLT(colorp, *ncolors, DoAll, quant, True, &histinfo);
  537.         msg("try to make %d level color map\n", *ncolors);
  538.         i = -1;    /* redo */
  539.         }
  540.     }
  541. }
  542. dumpColor(wa->dpy, cmap, cquire);
  543. }
  544. return (wa->cmap=cmap);
  545. }
  546.  
  547. MapColor(img, rp, fsize)
  548. Image    *img;
  549. register byte    *rp;
  550. register int    fsize;
  551. {
  552. register byte    *bp=img->img_buf;
  553. XColor    *color = graylevel;
  554. register int    i, min=img->marray[img->fn].min;
  555. register LKT    *lktp=lkt;
  556. int    w=img->width;
  557. #ifdef    EXTENDED_COLOR
  558. int i_fact = get_iconsize(img, 0);
  559. byte    *scan =
  560. # ifdef    USE_LAST_LINE
  561.     bp + img->image->bytes_per_line*img->height - w;
  562. # else
  563.     nzalloc(w, 1, "no8_scan");
  564. # endif
  565. #endif
  566.  
  567. if (img->sub_img)    {
  568. register int    j;
  569.     rp += img->sub_img_y * w + img->sub_img_x;
  570.     bp += img->sub_img_y * w + img->sub_img_x;
  571.     for (i=0; i<img->sub_img_h; i++)    {
  572.     j = img->sub_img_w;
  573.     if (img->dpy_depth == 8)
  574.         while (j--)
  575.         bp[j] = color[dgt[lktp[(rp[j] - min)&0xFF]]].pixel;
  576.     else {
  577. #ifdef    EXTENDED_COLOR
  578.     LineScan(rp, scan, color, lktp, j, min, img->dpy_depth!=1);
  579.     Map_Scanline(img, &scan, &scan, img->sub_img_x, img->sub_img_y + i,
  580.         img->sub_img_w, i_fact);
  581. #else
  582.     goto    npseud;
  583. #endif
  584.     }
  585.     XPutImage(img->dpy, img->win, img->gc, img->image,
  586.         img->sub_img_x, img->sub_img_y + i,
  587.         img->sub_img_x, img->sub_img_y + i, img->sub_img_w, 1);
  588.     bp += w;
  589.     rp += w;
  590.     }
  591. } else    {
  592.     if (img->dpy_depth == 8)
  593.     for (i=0; i<fsize; i++)
  594.         bp[i] = color[dgt[lktp[(rp[i] - min)&0xFF]]].pixel;
  595.     else
  596. #ifdef    EXTENDED_COLOR
  597.     for (i=0; i<img->height; i++, rp+=w)    {
  598.         LineScan(rp, scan, color, lktp, w, min, img->dpy_depth!=1);
  599.         Map_Scanline(img, &scan, &scan, 0, i, w, i_fact);
  600.     }
  601. #else
  602. npseud:    prgmerr(DEBUGANY, "system is not compiled with non-PSEUDO color");
  603. #endif
  604.     /*    Time Consuming Work    */
  605.     XPutImage(img->dpy, img->win, img->gc, img->image, 0, 0,
  606.         0, 0, w, img->height);
  607. }
  608. #if    defined    EXTENDED_COLOR && !defined USE_LAST_LINE
  609.     free(scan);
  610. #endif
  611. }
  612.  
  613. #endif    DIRECT
  614.  
  615.  
  616.  
  617. #ifdef    C_TUNER
  618.  
  619. LoadImage(fp, imgp, name)
  620. FILE    *fp;
  621. image_information    **imgp;
  622. char    *name;
  623. {
  624. register int    i;
  625. register byte    *dp;
  626. int    state = FileLoad;
  627. image_information    *img = *imgp;
  628.  
  629. if (img)    {
  630. MType    map_index[MaxColors];
  631.     free(img->scan_data);
  632.     for (i=0; i<img->entries; i++)
  633.         map_index[i] = graylevel[i].pixel;
  634.     if (img->hist)    {
  635.     register int*    hp=img->hist;
  636.         for (i=HistoSize*img->img_channels; i--;)
  637.             hp[i] = 0;
  638.         XFreeColors(img->dpy, img->colormap, map_index, i, 0);
  639.     }
  640.     DestroyColorImage(img);
  641.     firstmap = 0;
  642.     img->name = str_save(name);
  643.     state = FileReLoad;
  644. }
  645. else    img = *imgp = zalloc(1, sizeof(*img), "rle-img");
  646.  
  647. init_img_info(img, Dpy, RLE, cmn_hd.color_dpy);
  648. img->IN_FP = fp;
  649. rw_set = False;    /* reset user color table. */
  650. init_img_flag(img);
  651. img->name = name;
  652.  
  653. #ifdef    _DEBUG_
  654.     message("marray=%u, img=%u\n", img->marray, img);
  655. #endif
  656. i = get_pic(multi_hd=0, "", NULL, imgp, MGray);
  657. if (i<0)    return    0;
  658.  
  659. /*==============================*
  660. *    it also sets fsize    *
  661. *==============================*/
  662. if (!Find_min_max(img, histinfo.histp=img->hist, img->data, Yes, 0))
  663.     return    state;
  664. if (fButton)    {
  665.     img->RGB = ButtonState(fButton) = ButtonSync;
  666.     img->setscale = ButtonState(hButton)==HistScaleSet;
  667.     img->update = ButtonState(DButton) =DataAnalys;
  668.     ChangeSlider(img, &slider, ESlider, LSlider, heqButt, EButton);
  669.     ResetORange(img);
  670.     DrawPanel();
  671. }
  672. img->curve = ETALinear;
  673. new_curve(lkt, histinfo, img->marray, img->curve, 0, img, img->w*img->h);
  674.  
  675. message("%s is %d(r) x %d(c) x %d(n) -- %d\n",
  676.     name, img->h, img->w, img->img_num, fsize);
  677.  
  678. if (img->dpy_depth < 24)
  679.     MapColor(img, img->scan_data, fsize,
  680.     graylevel, MAX(VCTEntry, img->marray[img->RGB%3].min));
  681. HistoHandle(img, &histinfo, Yellow);
  682. return    state;
  683. }
  684.  
  685.  
  686. CreateColorTuner(dpy, dpy1, img, create_panel, map_panel, set_gray)
  687. Display    *dpy, *dpy1;
  688. image_information    *img;
  689. {
  690. static    int    cct_set, cct;
  691. if (!cct_set++)    {
  692.     Set_Monitor(Monitor, dpy, dpy1, img->colormap);
  693.     VCTEntry = GetVctEntry(Dpy, Screen, Monitor[0].cmap, set_gray);
  694.     Light = GetGray(dpy, img->colormap, ncolors, 224);
  695. }
  696. if (create_panel && !cct++) {
  697.     I_ED.copy = nzalloc(sizeof(*I_ED.copy), 1, "I_copy");
  698.     map_panel = CreateTuner(img, 5, darkGray, map_panel);
  699.     img->curve = ETALinear;
  700. }
  701. return    create_panel;
  702. }
  703.  
  704. #else    /* B-W handlers */
  705.  
  706. LoadImage(fp, imgf, name)
  707. FILE*    fp;
  708. Image    **imgf;    /* must be a double pointer */
  709. char    *name;
  710. {
  711. int    frames=(*imgf) ? (*imgf)->frames : 0, state=FileReLoad;
  712. register int    i;
  713. register Image    *img;
  714.  
  715. cursor = XCreateFontCursor(Dpy, XC_umbrella);
  716. if (*imgf)    frames=(*imgf)->frames;
  717.  
  718. cmn_hd.IN_FP = fp;    cmn_hd.in_type = IMAGE_INIT_TYPE;
  719. if ((*cmn_hd.header_handle)(HEADER_READ, &cmn_hd, 0, 0, False))
  720.     return    False;
  721.  
  722. if (cmn_hd.in_form != IFMT_BYTE && !WaitOk(cmn_hd.frames & -8 ? AbortButt : 0,
  723.     "images isn't in byte format", 0))    return    False;
  724.  
  725. cmn_hd.o_form = IFMT_BYTE;
  726. cmn_hd.pxl_out = 1;
  727.  
  728. if (fsize*frames != row*cln*frm)    {
  729.     if (*imgf && (*imgf)->win) {
  730.         DestroyImage(*imgf);
  731.         state = FileReLoad;
  732.     }
  733.     else    state = FileLoad;
  734.     BuildImage(imgf, name, cln, row, frames!=frm ? frm : 0,
  735.         cmn_hd.in_type, HIPS, IBNeed);
  736.     cmn_hd.data = NULL;
  737. }
  738. else    cmn_hd.data = (*imgf)->data;
  739.  
  740. img = *imgf;
  741. histinfo.histp = img->hist;
  742. img->colormap = Monitor[0].cmap;
  743. img->channels = img->dpy_channels = 1;
  744. img->history = cmn_hd.history;
  745. cmn_hd.parts = img->parts;
  746. cmn_hd.stack_num = img->stack_num;
  747. memcpy(&img->superimpose, &cmn_hd.superimpose, 6 + 11*sizeof(int));
  748. if (cmn_hd.desc)
  749.     img->desc = str_save(cmn_hd.desc);
  750. #ifdef    _DEBUG_
  751. message("buf=%u, marray=%u, img=%u\n", img->data, img->marray, img);
  752. #endif
  753.  
  754. fsize = img->width * img->height;
  755. cmn_hd.load_all = img->frames = frm;
  756.  
  757. (cmn_hd.std_swif)(FI_LOAD_FILE, &cmn_hd, 0, 0, False);
  758. fclose(fp);    (*imgf)->data = cmn_hd.data;
  759.  
  760. /*===============================================================
  761. %    compute the min, max, if allocating img->hist here,    %
  762. %    scale Global hist to img->hist + HistoSize*i        %
  763. %    after histogram return. (using for loop HistoSize times    %
  764. %  for loop do checking first and finish 0 out with i = -1    %
  765. ===============================================================*/
  766. for (i=img->frames; i--;)
  767. {
  768. register byte    *dp=img->data + i * fsize;
  769.     img->fn = i;
  770.     Find_min_max(img, histinfo.histp, dp, Yes, True);
  771. #ifdef    DIRECT
  772.     {
  773.     register int    j;
  774.     for (j=0; j<fsize; j++, dp++)
  775.         if (*dp < VCTEntry)    *dp = VCTEntry;
  776.     }
  777. #endif
  778. }
  779.  
  780. i = img->fn;    /* keep 0 all the way to the end */
  781. img->mmm = img->marray[i];
  782. SetSBarRPos(LSlider, img->linearlow=img->mmm.min, 1);
  783. SetSBarRPos(LSlider, img->linearup=img->mmm.max, 2);
  784. img->curve = ETALinear;
  785. img->setscale = ButtonState(hButton)==HistScaleSet;
  786. img->update = ButtonState(DButton) = DataAnalys;
  787. DrawButton(DButton);
  788. ChangeSlider(img, &slider, ESlider, LSlider, heqButt, EButton);
  789. SetShowFramePos(img, fButton, i);
  790. ResetORange(img);
  791. new_curve(lkt, &histinfo, img->marray, img->curve, 0, img, fsize);
  792.  
  793. message("%s is %d(r) x %d(c) x %d(f) -- %d [%d channels]\n",
  794.     name, row, cln, frm, fsize*frm, img->channels);
  795.  
  796. MapColor(img, img->data, fsize
  797. #ifdef    DIRECT
  798.     , graylevel, MAX(VCTEntry, img->marray[i].min)
  799. #endif
  800. );
  801.  
  802. img->mmm = img->marray[i];
  803. HistoHandle(img, &histinfo, lightGray);
  804.  
  805. /* select events to wait for. STRANGE ? this is not always useful  */
  806. XSelectInput(img->dpy, img->win, I_Mask | KeyPressMask |
  807.     StructureNotifyMask /*| ResizeRedirectMask*/);
  808. XSelectInput(img->dpy, img->icon, ExposureMask | StructureNotifyMask);
  809. return    state;
  810. }
  811.  
  812. #endif    C_TUNER
  813.  
  814.  
  815. ToImageStr(img, fcolor, sub_w, fh, x0, y0)
  816. Image    *img;
  817. register int    fcolor;
  818. {
  819. register int    h, y, xw, w=img->width;
  820. XImage    *ximg = XGetImage(img->dpy, img->win, x0, y=y0, sub_w, h=fh,
  821.         AllPlanes, img->image->format);
  822. register byte    *px = (byte *) ximg->data;
  823. byte    *p[3], *scan[3];
  824. int    ff=get_iconsize(img, 0),    pxw=ximg->bytes_per_line;
  825. long    mask24 = 0xFFFFFF;
  826.  
  827. if (img->dpy_depth > 8)    {
  828.     pxw <<= 2;
  829.     fcolor = (fnt_b << 16) & (fnt_g << 8) & fnt_r;
  830.     if (ImageByteOrder(img->dpy) != LSBFirst)
  831.         mask24 <<= 8;
  832. }
  833.     if (img->dpy_channels==1)    {
  834.     register byte    *pi = p[0] = img->data + y*w + x0;
  835.     scan[0] = (img->color_dpy ? img->scan_data : (byte*)img->image->data)
  836.         + y*w + x0;
  837.     for (; h--; p[0]=(pi+=w), px+=pxw, scan[0]+=w) {
  838.         for (xw=sub_w; xw--;)    {
  839.         if (img->dpy_depth > 8)    {
  840.             if (((int*)px)[xw] & mask24 != fcolor)
  841.                 continue;
  842.         } else if (px[xw] != fcolor)    continue;
  843.             pi[xw] = fcolor;
  844.         }
  845. #    ifdef    C_TUNER
  846.         Map_Scanline(img, p, scan, x0, y++, sub_w, ff);
  847. #    else
  848.         memcpy(scan[0], px, sub_w);
  849. #    endif
  850.     }
  851.     } else {
  852.     p[0] = img->data + w*img->dpy_channels*y + x0;
  853.     scan[2] = img->scan_data + w*(img->dpy_channels*y-1) + x0;
  854.     for (; h--; px+=pxw, p[0]+=w*img->dpy_channels)    {
  855.         p[1] = p[0] + w;
  856.         p[2] = p[1] + w;
  857.         for (xw=sub_w; xw--;)    {
  858.             if (img->dpy_depth > 8)    {
  859.             if (((int*)px)[xw] & mask24 != fcolor)
  860.                 continue;
  861.             } else if (px[xw] != fcolor)    continue;
  862.             p[0][xw] = fnt_r;
  863.             p[1][xw] = fnt_g;
  864.             p[2][xw] = fnt_b;
  865.         }
  866. #    ifdef    C_TUNER
  867.         scan[0] = scan[2] + w;
  868.         scan[1] = scan[0] + w;
  869.         scan[2] = scan[1] + w;
  870.         Map_Scanline(img, p, scan, x0, y++, sub_w, ff);
  871. #    endif
  872.     }
  873.     }
  874. PlaceArea(img, x0, y0, sub_w, fh);
  875. img->update = True;
  876. XDestroyImage(ximg);
  877. }
  878.  
  879. char    *DrawShape[]={" ", "Arc", "Line", "Rectangle"};
  880.  
  881. DrawInImage(img, y0, emsg, buf)
  882. Image    *img;
  883. int    *y0;
  884. char    *emsg, *buf;
  885. {
  886. int    b, lw=1, shape=DrawsLine, x, y, si=img->o_type==HIPS,
  887.     color = AdoptColor(img, fnt_r, fnt_g, fnt_b, precision);
  888. Cursor    dii_cursor=XCreateFontCursor(img->dpy, XC_crosshair);
  889.     if (img->dpy_depth > 8)    {
  890.         WaitOk(0, "no draw for true color display", 0);
  891.         return;
  892.     }
  893.     if (!img->color_dpy)    color >= 2;
  894. while(1)    {
  895.     XSetLineAttributes(img->dpy, img->gc, lw, 0, CapButt, 0);
  896.     b = WaitButtonPress_n_InfoImage(img, &histinfo, y0, dii_cursor);
  897.     RemoveImageEvent(img, ButtonAction)    XBell(img->dpy, 0);
  898.     if (b == Button3)    break;
  899.     if (b == Button2)    {
  900.         shape = shape+1 & 3;
  901.         if (!shape)    {
  902.             shape++;
  903.             sprintf(buf, "line width = %d", lw);
  904.             Get_Note_Input(buf, 16, 8, "width ", Green, 0);
  905.             sscanf(buf, "%d", &lw);
  906.         }
  907.         DisplayMessage(NoteWin, DrawShape[shape], 4, 0);
  908.         continue;
  909.     }
  910.     *y0 = SetParameterWin(img, img->event, img->font_h, 0);
  911.     TrackSubWin(img, &histinfo, x=img->event->xbutton.x,
  912.         y=img->event->xbutton.y, shape, Button1Mask, *y0);
  913.     DisplayMessage(NoteWin, "press MIDDLE button to comfrim", 4, 0);
  914.     b = WaitButtonPress_n_InfoImage(img, &histinfo, y0, dii_cursor)
  915.         == Button2;
  916.     XSetForeground(img->dpy, img->gc, color);
  917.     Draws(img, 0, !b, img->sub_img);
  918.     if (b)    {    /* comfirm    */
  919.         superimpose_add_elem(img, lw, color, shape, 0, 0, CapButt, 0);
  920.         if (!si) embed_image(img, lw, color, x, y);
  921.         img->update = True;
  922.     }
  923.     DisplayMessage(NoteWin, emsg, 4, img->sub_img=0);
  924. }
  925. XSetLineAttributes(img->dpy, img->gc, 0, 0, CapButt, 0);
  926. }
  927.  
  928. AdoptColor(img, r, g, b, prec)
  929. Image    *img;
  930. {
  931. register int    c = img->color_form==CFM_SCF ? CloseColor_in_Map
  932.         (img->in_cmap, img->cmaplen, r, g, b, prec) :
  933.         (RED_to_GRAY * r + GREEN_to_GRAY * g + BLUE_to_GRAY * b) >> 8;
  934. TopWindow(img, 0);
  935. Exposure_handler(img->event, img);
  936. return    c;
  937. }
  938.  
  939. embed_image(img, lw, color, x, y)
  940. register U_IMAGE*    img;
  941. register int    x, y;
  942. {
  943. register int    w = img->sub_img_w,    h = img->sub_img_h;
  944.     switch (img->sub_img)    {
  945.     case DrawsLine:
  946.         if (w < 0)    {    x += w;    w = -w;    }
  947.         if (h < 0)    {    y += h;    h = -h;    }
  948.         break;
  949.     case DrawsArc:
  950.         x = img->sub_img_x - w;
  951.         y = img->sub_img_y - h;
  952.         h <<= 1;    w <<= 1;
  953.         break;
  954.     case DrawsRect:
  955.         if (x > img->sub_img_x)
  956.             x = img->sub_img_x;
  957.         if (y > img->sub_img_y)
  958.             y = img->sub_img_y;
  959.     }
  960.     x -= lw;    y -= lw;
  961.     w += lw << 1;    h += lw << 1;
  962.     bound_check(w, x, img->width);
  963.     bound_check(h, y, img->height);
  964.     ToImageStr(img, color, w, h, x, y);
  965. }
  966.  
  967. CombineImage_Draws(img, x, y, fnt_w, fnt_h, color)
  968. Image    *img;
  969. register int    x, y, fnt_w, fnt_h;
  970. {
  971. if (img->superimpose)    {
  972. register superimpose_elems*    sip=img->superimpose[1] + img->texts;
  973.     fnt_w *= sip->cols;     fnt_h *= sip->rows;
  974. }
  975.     y -= img->ascent;
  976.     if (fnt_w + x >= img->width)
  977.         fnt_w = img->width - x - 1;
  978.     if (fnt_h + y >= img->height)
  979.         fnt_h = img->height - y - 1;
  980.     ToImageStr(img, color, fnt_w, fnt_h, x, y);
  981. }
  982.  
  983.